## -*- coding: utf-8 -*-

#   Copyright (C) 2007, 2008 Yves Junqueira (yves@cetico.org) 
#
#    This file is part of GeekDNS.
#
#    GeekDNS is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#
#    GeekDNS is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with GeekDNS.  If not, see <http://www.gnu.org/licenses/>.


"""
DNS management.
"""
# I hate myself for having written many things in pt_BR here.

import logging
from datetime import datetime
import turbogears
from turbogears import controllers, expose, redirect
from turbogears import identity, config, validate, error_handler
from turbogears import widgets, flash

from widgets import DNSDomainFields, DNSDomainSchema
from widgets import dns_edit_form, edit_domain_record_form
from widgets import new_domain_form, new_domain_record_form

from model import *

log = logging.getLogger("geekroot.dns")

class DNSPanel(controllers.Controller):
    @expose(template=".templates.dns")
    @identity.require(identity.not_anonymous())
    def index(self):
        domains = \
        DNSDomain.select(DNSDomain.q.ownerID==turbogears.identity.current.user.id
        )
        return dict(domains=domains)

    @expose(template=".templates.dominio_adiciona_registro")
    @identity.require(identity.not_anonymous())
    def dominio_adiciona_registro(self, domain_name, tg_errors=None):
        """Formulario de adição de REGISTRO dns
        """
        if tg_errors:
            flash("Dados inválidos. Veja abaixo")
        domain = DNSDomain.select(AND(
            DNSDomain.q.name==domain_name,
            DNSDomain.q.ownerID==turbogears.identity.current.user.id))[0]
        data = { 'name' : domain.name, #can also be a sub-domain 
            'domain_id' : domain.id,
            'domain_name' : domain.name # used for validation only
            }
        return dict(form=new_domain_record_form, data=data,
            domain=domain)

    @expose()
    @validate(form=new_domain_record_form)
    @error_handler(dominio_adiciona_registro)
    @identity.require(identity.not_anonymous())
    def dominio_registro_insere(self, **kw):

        rec=DNSRecord(
                domainID=kw['domain_id'],
                type=kw['type'],
                name=kw['name'],
                prio=kw['prio'],
                content=kw['content']
                )
        dom=DNSDomain.select(DNSDomain.q.id==kw['domain_id'])[0]
        dom.update_serial()
        flash(u"Registro inserido")
        raise turbogears.redirect(['/painel','dns', 'dominio_editar',
            rec.domain.name])

    @expose(template=".templates.dominio_adiciona")
    @identity.require(identity.not_anonymous())
    def dominio_adiciona(self, tg_errors=None):
        """Formulário de adição de novo domínio no DNS
        """
        if tg_errors:
                    flash("Dados inválidos. Veja abaixo")
        return dict(form=new_domain_form)

    @expose(template=".templates.dominio_editar")
    @identity.require(identity.not_anonymous())
    def dominio_editar(self, domain_name, tg_errors=None):
        """Formulário de edição de domínio no DNS
        """
        if tg_errors:
                    flash("Dados inválidos. Veja abaixo")
        domain = \
        DNSDomain.select(AND(
        DNSDomain.q.name==domain_name,
        DNSDomain.q.ownerID==turbogears.identity.current.user.id
        ))[0]
        records = DNSRecord.select(DNSRecord.q.domainID==domain.id)
        #dnsrecord_edit_form._domain = domain.name
        return dict(domain=domain, records=records,
            form=dns_edit_form)

    @expose()
    @identity.require(identity.not_anonymous())
    def dominio_apagar(self, domain_id):
        """Apaga *dominio* no banco
        """
        dom=DNSDomain.select(AND(
        DNSDomain.q.id==domain_id,
        DNSDomain.q.ownerID==turbogears.identity.current.user.id
        ))[0]
        log.info("Apagando dominio: %s" % dom.name)
        dom.destroySelf()

        raise turbogears.redirect(['/painel',
            'dns'])

    @expose()
    @identity.require(identity.not_anonymous())
    def dominio_apagar_registro(self, record_id):
        """Apaga registro de dominio no banco
        """
        record = \
        DNSRecord.select(AND(
        DNSRecord.q.id==record_id,
        DNSRecord.q.domainID==DNSDomain.q.id,
        DNSDomain.q.ownerID==turbogears.identity.current.user.id
        ))[0]
        domain_name=record.name

        log.debug("Domínio encontrado: %s" % domain_name)
        dom=record.domain
        record.destroySelf()
        dom.update_serial()

        raise turbogears.redirect(['/painel',
            'dns', 'dominio_editar',
                dom.name])

    @expose(template=".templates.dominio_editar_registro")
    @identity.require(identity.not_anonymous())
    def dominio_editar_registro(self, record_id, tg_errors=None):
        """Formulario de adição de REGISTRO dns
        """
        if tg_errors:
            flash("Dados inválidos. Veja abaixo")
        record = \
        DNSRecord.select(
        DNSRecord.q.id==record_id,
        )[0]
        assert record.domain.owner.id == turbogears.identity.current.user.id
        data = { 
            'name' : record.name, #can also be a sub-domain
            'type' : record.type,
            'content' : record.content,
            'prio' : record.prio, # used for validation only
            'ttl' : record.ttl,
            'record_id' : record.id,
            'domain_name' : record.domain.name
            }
        return dict(form=edit_domain_record_form, data=data,
            domain=record.domain)

    @expose()
    @validate(form=edit_domain_record_form)
    @error_handler(dominio_editar_registro)
    @identity.require(identity.not_anonymous())
    def dominio_atualiza_registro(self, **kw):
        rec = \
        DNSRecord.select(
        DNSRecord.q.id==kw['record_id'],
        )[0]
        assert rec.domain.owner.id == turbogears.identity.current.user.id

        rec.type=kw['type']
        rec.name=kw['name']
        rec.prio=kw['prio']
        rec.content=kw['content']
        rec.domain.update_serial()
        flash(u"Registro atualizado")
        raise turbogears.redirect(['/painel','dns', 'dominio_editar',
            rec.domain.name])

    @expose()
    @validate(form=new_domain_form)
    @error_handler(dominio_adiciona)
    @identity.require(identity.not_anonymous())
    def dominio_insere(self, domain_name,  main_address):
        """Insere dominio no banco de dados
        """
        dom=DNSDomain(name=domain_name,type='NATIVE',
            owner=turbogears.identity.current.user)
        now = datetime.now()
        serial = now.strftime("%Y%m%d01")
        soa=DNSRecord(
            domain=dom,
            type="SOA",
            name=domain_name,
            content="ns1.yourbase.com.br hostmaster.yourbase.com.br \
%s %s %s %s %s" % ( serial, '10800', '3600', '1209600', '3600'))
        ns1=DNSRecord(
            domain=dom,
            type="NS",
            name=domain_name,
            content="NS1.YOURBASE.COM.BR")
        ns2=DNSRecord(
            domain=dom,
            type="NS",
            name=domain_name,
            content="NS2.YOURBASE.COM.BR")
        if main_address:
            mx=DNSRecord(
                domain=dom,
                type="MX",
                name=domain_name,
                prio=0,
                content=domain_name)
            a=DNSRecord(
                domain=dom,
                type="A",
                name=domain_name,
                prio=0,
                content=main_address)
            if not domain_name.startswith('www.'):
                awww=DNSRecord(
                domain=dom,
                type="A",
                name="www."+domain_name,
                prio=0,
                content=main_address)
        flash(u"Domínio adicionado")        
        raise turbogears.redirect(['/painel','dns'])
 
